#include "mode_manage.h"
#include "occ_mode.h"
#include "vac_mode.h"
#include "switch_mode.h"
#include "systime.h"
#include "relay_ctrl.h"
#include "key.h"
#include "pir_sensor_detect.h"
#include "adc_driver.h"
#include "device.h"
#include "pir_sensor_sensitivity.h"
#include "brightness_sensor_mode.h"
#include "brightness_custom.h"
#include "indicator.h"
#include "shell_color_selector.h"

#define POWER_START_UP_S 1 // 从上电到继电器动作的延时时间
#define POWER_UP_DELAY 15  // 单位s，上电延时时间

#define PIR_WARMUP_SAMPLE 20 // 单位ms
#define PIR_WARMUP_CNT 10    // PIR波形连续200ms非高，即认定为热机完成

#define PIR_WARMUP_FILTER 2500 // ms，关闭继电器PIR的滤波时间

// #define PIR_MAX_LIMIT                   (ADC_TOP_DIGITAL-81) //低于PIR热机高电平400mV

#define PIR_OK_LIMIT_THRESHOLD 768

typedef enum
{
    STATE_POWERUP_START_UP,
    STATE_POWERUP_INIT,
    STATE_POWERUP_DELAY,
    STATE_POWERUP_PIROK,
    STATE_POWERUP_RELYOFF,
    STATE_POWERUP_FINISH,

    STATE_DET,

    STATE_BRIGHTNESS_CUSTOM,
    STATE_SHELL_COLOR_SELECTOR,

} mode_manage_state_e;

typedef enum
{
    TYPE_NULL,
    OCC_MODE,
    VAC_MODE,
    SWITCH_MODE,
    CUSTOM_BRIGHTNESS_MODE,
    CUSTOM_SHELL_COLOR_MODE,
} mode_manage_type_e;

typedef struct
{
    uint8_t cnt;
    uint16_t val;
} pir_warmup_t;

static struct
{
    timestamp_t time;
    mode_manage_state_e state;
    pir_warmup_t pir_warmup;
    mode_manage_type_e mode;
    mode_manage_type_e det_mode;
} mode_manage_ctx;

void mode_manage_init(void)
{
    occ_mode_init();
    vac_mode_init();
    switch_mode_init();
    brightness_custom_init();
    shell_color_selector_init();

    mode_manage_ctx.state = STATE_POWERUP_START_UP;
    mode_manage_ctx.pir_warmup.cnt = 0;
    mode_manage_ctx.pir_warmup.val = 0;
    mode_manage_ctx.mode = TYPE_NULL;
    mode_manage_ctx.det_mode = TYPE_NULL;
}

void mode_manage_task(void)
{
    switch (mode_manage_ctx.state)
    {
    case STATE_POWERUP_START_UP:
        relative_time_add_sec(&mode_manage_ctx.time, POWER_START_UP_S);
        mode_manage_ctx.state = STATE_POWERUP_INIT;
        break;
    case STATE_POWERUP_INIT:
        if (is_relative_time_timeout(&mode_manage_ctx.time))
        {
            set_relay_sw(RELAY_ON);
            if (get_shell_color() == SHELL_COLOR_WHITE)
            {
                set_indicator_sw(IND_WHITE_SHELL);
            }
            else if (get_shell_color() == SHELL_COLOR_BLACK)
            {
                set_indicator_sw(IND_BLACK_SHELL);
            }
            set_key_switch(KEY_DISABLE);
            pir_sensor_set_status(PIR_SENSOR_DISABLED);
            relative_time_add_sec(&mode_manage_ctx.time, POWER_UP_DELAY); // 上电延时15s
            mode_manage_ctx.state = STATE_POWERUP_DELAY;
        }
        break;
    case STATE_POWERUP_DELAY:
        if (is_relative_time_timeout(&mode_manage_ctx.time))
        {
            mode_manage_ctx.state = STATE_POWERUP_PIROK;
            relative_time_add_ms(&mode_manage_ctx.time, PIR_WARMUP_SAMPLE);
        }
        break;
    case STATE_POWERUP_PIROK:
        if (is_relative_time_timeout(&mode_manage_ctx.time))
        {
            relative_time_add_ms(&mode_manage_ctx.time, PIR_WARMUP_SAMPLE);
            mode_manage_ctx.pir_warmup.val = get_pir_val();
            if (mode_manage_ctx.pir_warmup.val < PIR_OK_LIMIT_THRESHOLD)
            {
                mode_manage_ctx.pir_warmup.cnt++;
            }
            else
            {
                mode_manage_ctx.pir_warmup.cnt = 0;
            }
            if (mode_manage_ctx.pir_warmup.cnt >= PIR_WARMUP_CNT)
            { // PIR连续200ms非高，即位热机完成
                mode_manage_ctx.state = STATE_POWERUP_RELYOFF;
                mode_manage_ctx.pir_warmup.cnt = 0;
            }
        }
        break;
    case STATE_POWERUP_RELYOFF:
        set_relay_sw(RELAY_OFF);
        set_indicator_sw(IND_OFF);
        relative_time_add_ms(&mode_manage_ctx.time, PIR_WARMUP_FILTER);
        mode_manage_ctx.state = STATE_POWERUP_FINISH;
        break;
    case STATE_POWERUP_FINISH:
        if (is_relative_time_timeout(&mode_manage_ctx.time))
        {
            set_key_switch(KEY_ENABLE);
            pir_sensor_set_status(PIR_SENSOR_ENABLED);
            set_indicator_sw(IND_PIR);
            mode_manage_ctx.state = STATE_DET;

            mode_manage_ctx.mode = TYPE_NULL;
            mode_manage_ctx.det_mode = TYPE_NULL;
        }
        break;
    case STATE_DET:
        if (PIR_SENSITIVITY_OFF == get_pir_sensor_sensitivity())
        { // PIR关闭普通开关
            mode_manage_ctx.det_mode = SWITCH_MODE;
        }
        else if (BRIGHTNESS_VAC_MODE == get_brightness_sensor_mode())
        { // VAC mode
            mode_manage_ctx.det_mode = VAC_MODE;
        }
        else
        {
            mode_manage_ctx.det_mode = OCC_MODE;
        }

        if (is_key_long_press())
        { // 按键长按
            if (BRIGHTNESS_CUSTOM == get_brightness_sensor_mode())
            { // 客户定制亮度
                mode_manage_ctx.det_mode = CUSTOM_BRIGHTNESS_MODE;
            }
            else if (PIR_SENSITIVITY_OFF == get_pir_sensor_sensitivity())
            { // 外壳颜色设置
                mode_manage_ctx.det_mode = CUSTOM_SHELL_COLOR_MODE;
            }
        }

        if (mode_manage_ctx.mode != mode_manage_ctx.det_mode)
        { // mode发生变化
            mode_manage_ctx.mode = mode_manage_ctx.det_mode;
            brightness_custom_init();
            occ_mode_state_deinit();
            vac_mode_state_deinit();
            switch_mode_state_deinit();
            shell_color_selector_init();
        }

        if (CUSTOM_BRIGHTNESS_MODE == mode_manage_ctx.mode)
        { // 客户定制亮度处理
            mode_manage_ctx.state = STATE_BRIGHTNESS_CUSTOM;
        }
        else if (SWITCH_MODE == mode_manage_ctx.mode)
        {
            switch_mode_task();
        }
        else if (VAC_MODE == mode_manage_ctx.mode)
        {
            vac_mode_task();
        }
        else if (OCC_MODE == mode_manage_ctx.mode)
        {
            occ_mode_task();
        }
        else if (CUSTOM_SHELL_COLOR_MODE == mode_manage_ctx.mode)
        {
            mode_manage_ctx.state = STATE_SHELL_COLOR_SELECTOR;
        }

        break;
    case STATE_BRIGHTNESS_CUSTOM:
        if (is_brightness_custom_finish())
        { // 客户定制亮度处理结束
            mode_manage_ctx.state = STATE_DET;
        }
        else
        {
            brightness_custom_process_task(); // 客户定制亮度处理任务
        }
        break;
    case STATE_SHELL_COLOR_SELECTOR:
        if (is_shell_color_selector_finish())
        {
            mode_manage_ctx.state = STATE_DET;
        }
        else
        {
            shell_color_selector_process_task();
        }
        break;

    default:
        break;
    }
}
